package com.ts.api.module.match.market.internal.sort.strategy;

import com.gitee.apanlh.util.base.CollUtils;
import com.gitee.apanlh.util.random.RandomUtils;
import com.ts.api.module.channel.entity.po.ChannelMarketPO;
import com.ts.api.module.match.market.internal.sort.model.ChannelMarketSort;
import com.ts.api.module.match.market.internal.sort.model.ChannelMarketSortResult;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 *  渠道贷超-权重
 *
 *  @author Pan
 */
@Component
public class ChanelMarketWeightSort implements ChannelMarketSortStrategy {

    @Override
    public ChannelMarketSortResult sort(ChannelMarketSort channelMarketSort) {
        List<ChannelMarketPO> listMarket = channelMarketSort.getListMarket();
        List<ChannelMarketPO> listMarketCopy = ChanelMarketWeightSort.randomWeight(CollUtils.copy(listMarket));
        return ChannelMarketSortResult.of(listMarketCopy);
    }

    /**
     *  随机权重算法
     *
     *  @author Pan
     *  @param  listMarketCopy
     *  @return List
     */
    public static List<ChannelMarketPO> randomWeight(List<ChannelMarketPO> listMarketCopy) {
        //  累积权重
        Integer totalWeight = 0;
        for (ChannelMarketPO channelMarketPO : listMarketCopy) {
            totalWeight += channelMarketPO.getWeight();
        }

        if (totalWeight == 0) {
            return listMarketCopy;
        }

        //  随机累计权重值
        int random = RandomUtils.randomInt(0, totalWeight);

        //  累积权重计算
        int sum = 0;
        ChannelMarketPO selected = null;
        for (ChannelMarketPO channelMarketPO : listMarketCopy) {
            Integer weight = channelMarketPO.getWeight();

            //  0%权重不计数
            if (weight <= 0) {
                continue;
            }

            sum += weight;
            if (random <= sum) {
                selected = channelMarketPO;
                break;
            }
        }

        //  将被选项移动到首位
        if (selected != null) {
            listMarketCopy.remove(selected);
            listMarketCopy.addFirst(selected);
        }
        return listMarketCopy;
    }
}
